package com.hgy.plugin.security;

import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.CachingSecurityManager;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.apache.shiro.web.servlet.ShiroFilter;

import com.hgy.common.utils.ArrayUtil;
import com.hgy.common.utils.StringUtil;
import com.hgy.plugin.security.realm.SmartCustomRealm;
import com.hgy.plugin.security.realm.SmartJdbcRealm;

/**
 * 安全过滤器
 * 
 * @author alone
 *
 */
public class SmartSecurityFilter extends ShiroFilter{

	/**
	 * Filter 初始化
	 */
	@Override
	public void init() throws Exception {
		super.init();
		WebSecurityManager webSecurityManager = super.getSecurityManager();
		setRealm(webSecurityManager);
		setCache(webSecurityManager);
	}
	
	/**
	 * 设置Realm, 可同时支持多个 Realm 并按照先后顺序 用逗号隔开
	 * 
	 * @param webSecurityManager
	 */
	private void setRealm(WebSecurityManager webSecurityManager) {
		String securityRealms = SecurityConfig.getRealms();
		if(StringUtil.isNotEmpty(securityRealms)){
			String[] securityRealmArray = securityRealms.split(",");
			if(ArrayUtil.isNotEmpty(securityRealmArray)){
				// 使Realm 具备唯一顺序性
				Set<Realm> realms = new LinkedHashSet<Realm>();
				for (String securityRealm : securityRealmArray) {
					if(securityRealm.equalsIgnoreCase(SecurityConstant.REALMS_JDBC)){
						addJdbcRealm(realms);
					}else if(securityRealm.equalsIgnoreCase(SecurityConstant.REALMS_CUSTOM)){
						addCustomRealm(realms);
					}
				}
				RealmSecurityManager realmSecurityManager = (RealmSecurityManager) webSecurityManager;
				realmSecurityManager.setRealms(realms);
			}
		}
	}
	
	/**
	 * 添加基于 JDBC 的Realm, 需配置相关SQL查询
	 * 
	 * @param realms
	 */
	private void addJdbcRealm(Set<Realm> realms) {
		SmartJdbcRealm smartJdbcRealm = new SmartJdbcRealm();
		realms.add(smartJdbcRealm);
	}
	
	/**
	 * 添加基于定制化的  Realm, 需事先SmartSecurity 接口
	 * @param realms
	 */
	private void addCustomRealm(Set<Realm> realms) {
		// 获取SmartSecurity 对象
		SmartSecurity smartSecurity = SecurityConfig.getSmartSecurtiy();
		SmartCustomRealm smartCustomRealm = new SmartCustomRealm(smartSecurity);
		realms.add(smartCustomRealm);
	}
	
	/**
	 * 设置 Cache, 用于减少数据库查询次数, 降低 I/O 访问
	 * 
	 * @param webSecurityManager
	 */
	private void setCache(WebSecurityManager webSecurityManager) {
		if(SecurityConfig.isCacheable()){
			CachingSecurityManager cachingSecurityManager = (CachingSecurityManager) webSecurityManager;
			CacheManager cacheManager = new MemoryConstrainedCacheManager();
			cachingSecurityManager.setCacheManager(cacheManager);
		}
	}
	
}
